iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

Day7 第一個房客,建立租戶

在『設計格局,Django 多租戶架構』我們已經把房間準備好了,接下來就來迎接第一個租戶吧!

多租戶指令說明

工欲善其事,必先利其器。要迎接租戶前,先來看看之後要怎麼與租戶進行良好溝通,了解多租戶指令就是進行溝通的最佳捷徑。

create_tenant 建立租戶

建立一個新租戶,以下為參數說明與範例:

--schema_name 為 schema 名稱

--name 租戶名稱

--paid_until 截止日期

--on_trial 正在試用

--domain-domain 網域名稱

--domain-is_primary 是否為主要網域名稱

./manage.py create_tenant \
    --schema_name=example01 \
    --name=example01 \
    --paid_until=2099-12-31 \
    --on_trial=0 \
    --domain-domain=example01.localhost \
    --domain-is_primary=False

delete_tenant 刪除租戶

刪除一個現有租戶

./manage.py delete_tenant

clone_tenant 複製租戶

複製一個現有租戶

./manage.py clone_tenant

查看使用說明

./manage.py clone_tenant -h

migrate_schemas 資料庫遷移

遷移租戶共用資料表

./manage.py migrate_schemas

多進程遷移租戶共用資料表

./manage.py migrate_schemas --executor=multiprocessing

tenant_command 單獨租戶指令

匯入指定租戶的資料

./manage.py tenant_command loaddata --schema=customer1

all_tenants_command 全部租戶指令

在每個租戶上運行指令

./manage.py all_tenants_command loaddata

create_tenant_superuser 建立超級使用者

為租戶建立一個超級使用者,以下為參數說明與範例:

--username 指定使用者名稱

--schema 指定 schema 名稱

./manage.py create_tenant_superuser \
    --username=admin \
    --schema=new_tenant

重命名 schema

重新命名 schema 與更新資料庫對應的 Client

./manage.py rename_schema \
    --rename_from old_name \
    --rename_to new_name

檢查缺失的 schema table

如果找到缺失的 schema

./manage.py create_missing_schemas

建立第一個租戶

在建立租戶之前我們先看看調整為多租戶架構後網頁顯示的內容,已經無法正常顯示上次運行的 Django 預設網頁。

https://ithelp.ithome.com.tw/upload/images/20220919/201516563pfiEklJUm.png

建立一個名為 example01 的租戶

docker exec -it --workdir /opt/app/web example_tenant_web \
    python3.10 manage.py create_tenant \
        --schema_name=example01 \
        --name=example01 \
        --paid_until=2099-12-31 \
        --on_trial=0 \
        --domain-domain=example01.localhost \
        --domain-is_primary=False

...

[1/1 (100%) standard:example_first] === Starting migration
[1/1 (100%) standard:example_first] Operations to perform:
[1/1 (100%) standard:example_first]   Apply all migrations: admin, auth, contenttypes, customers, sessions, sites
[1/1 (100%) standard:example_first] Running migrations:
[1/1 (100%) standard:example_first]   Applying contenttypes.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying admin.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying admin.0002_logentry_remove_auto_add...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying admin.0003_logentry_add_action_flag_choices...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying contenttypes.0002_remove_content_type_name...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0002_alter_permission_name_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0003_alter_user_email_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0004_alter_user_username_opts...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0005_alter_user_last_login_null...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0006_require_contenttypes_0002...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0007_alter_validators_add_error_messages...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0008_alter_user_username_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0009_alter_user_last_name_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0010_alter_group_name_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0011_update_proxy_permissions...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying auth.0012_alter_user_first_name_max_length...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying customers.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying sessions.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying sites.0001_initial...
[1/1 (100%) standard:example_first]  OK
[1/1 (100%) standard:example_first]   Applying sites.0002_alter_domain_unique...
[1/1 (100%) standard:example_first]  OK

建立完成,透過 example01.localhost 來查看

https://ithelp.ithome.com.tw/upload/images/20220919/20151656RoF0OIrUAq.png

太好了,成功以多租戶架構建立了 django 服務。

為了之後進行多租戶架構的開發,馬上來建立第二個租戶 example02。

docker exec -it --workdir /opt/app/web example_tenant_web \
    python3.10 manage.py create_tenant \
        --schema_name=example02 \
        --name=example02 \
        --paid_until=2099-12-31 \
        --on_trial=0 \
        --domain-domain=example02.localhost \
        --domain-is_primary=False
[1/1 (100%) standard:example02] === Starting migration
[1/1 (100%) standard:example02] Operations to perform:
[1/1 (100%) standard:example02]   Apply all migrations: admin, auth, contenttypes, customers, sessions, sites
[1/1 (100%) standard:example02] Running migrations:
[1/1 (100%) standard:example02]   Applying contenttypes.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying admin.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying admin.0002_logentry_remove_auto_add...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying admin.0003_logentry_add_action_flag_choices...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying contenttypes.0002_remove_content_type_name...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0002_alter_permission_name_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0003_alter_user_email_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0004_alter_user_username_opts...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0005_alter_user_last_login_null...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0006_require_contenttypes_0002...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0007_alter_validators_add_error_messages...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0008_alter_user_username_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0009_alter_user_last_name_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0010_alter_group_name_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0011_update_proxy_permissions...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying auth.0012_alter_user_first_name_max_length...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying customers.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying sessions.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying sites.0001_initial...
[1/1 (100%) standard:example02]  OK
[1/1 (100%) standard:example02]   Applying sites.0002_alter_domain_unique...
[1/1 (100%) standard:example02]  OK

建立完成,透過 example02.localhost 來查看

https://ithelp.ithome.com.tw/upload/images/20220919/20151656vXlCUHfaZN.png

完美,第二個租戶也建立成功了。

Schema 結構

看似雙胞胎的兩個租戶實際上其實使用了不同的 schema,

public 為租戶共用 schema,

example01 為 example01 租戶獨立 schema,

example02 為 example02 租戶獨立 schema,

以下為當前資料庫結構:

                            List of relations
       Schema       |            Name            |    Type     |  Owner  
--------------------+----------------------------+-------------+---------
 public             | customers_client           | table       | db_user
 public             | customers_domain           | table       | db_user
 public             | django_content_type        | table       | db_user
 public             | django_migrations          | table       | db_user 

 example01          | auth_group                 | table       | db_user
 example01          | auth_group_permissions     | table       | db_user
 example01          | auth_permission            | table       | db_user
 example01          | auth_user                  | table       | db_user
 example01          | auth_user_groups           | table       | db_user
 example01          | auth_user_user_permissions | table       | db_user
 example01          | django_admin_log           | table       | db_user
 example01          | django_migrations          | table       | db_user
 example01          | django_session             | table       | db_user
 example01          | django_site                | table       | db_user
 
 example02          | auth_group                 | table       | db_user
 example02          | auth_group_permissions     | table       | db_user
 example02          | auth_permission            | table       | db_user
 example02          | auth_user                  | table       | db_user
 example02          | auth_user_groups           | table       | db_user
 example02          | auth_user_user_permissions | table       | db_user
 example02          | django_admin_log           | table       | db_user
 example02          | django_migrations          | table       | db_user
 example02          | django_session             | table       | db_user
 example02          | django_site                | table       | db_user

多租戶指令是與多租戶架構溝通的途徑之一,熟練之後我們甚至能將這些指令轉換為管理介面上的表單,讓有特殊權限的使用者只需要填寫表單就能執行特定的多租戶指令。

現在,房客已入住完成,是時候來認識一下模型了,下一回『認識模型,常用欄位與參數介紹 』


上一篇
Day6 設計格局,Django 多租戶架構
下一篇
Day8 認識模型,常用欄位與參數介紹
系列文
全能住宅改造王,Django 多租戶架構的應用 —— 實作一個電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言